package controllers;

import java.util.ArrayList;
import java.util.List;

import com.google.gson.JsonObject;
import com.sun.xml.internal.stream.Entity;

import controllers.Secure.Security;

import models.ActionItem;
import models.Entities;
import models.Idea;
import models.IdeaDeveloper;
import models.Log;
import models.Organization;
import models.OrganizationLead;
import models.Organizer;
import models.Topic;
import play.mvc.Controller;

public class SystemAdmin extends Controller {

	public static void LogView() {

		if (Security.connected().equals("administrator")) {
			render();
		} else {
			UserProfile.SelfUserProfile();
		}
	}

	/**
	 * this method views the log of the whole system
	 * 
	 * @author KimO
	 */
	public static void viewLog() {

		List<Log> logTable = Log.findAll();
		int maximum = (logTable.size() - 1);
		int minimum = ((logTable.size() - 200) > 0) ? (logTable.size() - 201)
				: 0;
		String[] logArray = new String[200];
		for (int i = maximum; i > minimum; i--) {
			if (!(logArray[i - minimum - 1] = Log.decodeAdmin(logTable.get(i)))
					.equals("")) {
				logArray[i - minimum - 1] = Log.decodeAdmin(logTable.get(i))
						+ "QQQ" + logTable.get(i).date;
			} else {
				if (minimum > 0)
					minimum--;
			}
		}
		renderJSON(logArray);

	}

	/**
	 * This method is used to render a list of log entries according to a
	 * certain test criteria
	 * 
	 * @param searchInput
	 *            the search input from the system administrator at which the
	 *            method will search
	 */
	public static void multiSearch(String searchInput) {
		String[] searchList = searchInput.split("AAA");
		List<Log> logResultList = Log.findAll();
		for (String searchItem : searchList) {
			if (searchItem == "") {
				break;
			}
			String[] oneSearch = searchItem.split(",");
			String type = oneSearch[0].toLowerCase();

			Long id = 0L;
			try {
				id = Long.parseLong(oneSearch[1]);
			} catch (Exception e) {
				try {
					if (type.equalsIgnoreCase("ideadeveloper")) {
						IdeaDeveloper ideaDev = (IdeaDeveloper.find(
								"username=?", oneSearch[1]).first());
						id = ideaDev.id;
					}
					if (type.equalsIgnoreCase("entity")) {
						Entities entit = Entities.find("name=?", oneSearch[1])
								.first();
						id = entit.id;
					}
					if (type.equalsIgnoreCase("topic")) {
						Topic topc = Topic.find("title=?", oneSearch[1])
								.first();
						id = topc.id;
					}
					if (type.equalsIgnoreCase("organization")) {
						Organization organizaton = Organization.find("name=?",
								oneSearch[1]).first();
						id = organizaton.id;
					}
					if (type.equalsIgnoreCase("idea")) {
						Idea ida = Idea.find("title=?", oneSearch[1]).first();
						id = ida.id;
					}
				} catch (Exception e2) {
					id = 0L;
				}
			}

			try {
				List<Log> resultLog = new ArrayList<Log>(0);
				for (int i = 0; i < logResultList.size(); i++) {
					Log log = ((Log) logResultList.get(i));
					if (log.ids.contains(id + "") && (log.types.contains(type))) {
						resultLog.add(log);
					}
				}
				logResultList = resultLog;
				if (id == 0L)
					id = Long.parseLong("abc");
			} catch (Exception e) {
				String[] logArray = new String[0];
				logArray = new String[1];
				logArray[0] = "No results matching your search critirea!";
			}
		}
		String[] logArray = new String[logResultList.size()];
		for (Log logEntry : logResultList) {
			logArray[logResultList.indexOf(logEntry)] = Log
					.decodeAdmin(logEntry) + "QQQ" + logEntry.date;
		}
		if (logArray.length == 0) {
			logArray = new String[1];
			logArray[0] = "No results matching your search critirea!";
		}
		renderJSON(logArray);
	}

	public static void AssignRole() {
		if (Security.connected().equals("administrator")) {
			render();
		} else {
			UserProfile.SelfUserProfile();
		}
	}

	/**
	 * This method allows the system admin to assign a role to an ideaDeveloper
	 * 
	 * @author Maryam
	 * 
	 * @param username
	 *            The username of the ideaDeveloper that is going to be assigned
	 * @param roleType
	 *            What kind of role the ideaDeveloper will have
	 * @param name
	 *            The name of the entity or organization that the ideaDeveloper
	 *            will be assigned to
	 */

	public static void assign(String username, String roleType, String name) {
		JsonObject json = new JsonObject();
		try {
			long countIdeaDeveloper = IdeaDeveloper.count("username = ?",
					username);
			if (countIdeaDeveloper == 0) {
				json.addProperty("output", "User not found");
			} else {
				IdeaDeveloper ideaDeveloper = (IdeaDeveloper) IdeaDeveloper
						.find("username = ?", username).fetch().get(0);

				if (roleType.equalsIgnoreCase("organizationLead")) {
					json.addProperty("output", assignLead(ideaDeveloper, name));
				} else {
					if (roleType.equalsIgnoreCase("organizerEntity")) {

						json.addProperty("output",
								assignOrganizerToEntity(ideaDeveloper, name));
					} else {
						if (roleType.equalsIgnoreCase("organizerTopic")) {
							json.addProperty("output",
									assignOrganizerToTopic(ideaDeveloper, name));
						}
					}
				}
			}
			renderJSON(json.toString());

		} catch (Exception e) {
			renderJSON("Error");
		}
	}

	/**
	 * This method assigns an idea developer as an organization lead to an
	 * organization
	 * 
	 * @author Maryam
	 * 
	 * @param ideaDeveloper
	 *            The idea developer that is going to be assigned
	 * @param organizationName
	 *            The name of the organization that the idea developer will be
	 *            assigned to
	 * @return the string that would be viewed to the user according to whether
	 *         the idea developer is assigned or not and why
	 */

	public static String assignLead(IdeaDeveloper ideaDeveloper,
			String organizationName) {
		long countOrganization = Organization.count("name = ?",
				organizationName);

		if (countOrganization == 0) {
			return "Organization not found";
		} else {
			Organization organization = (Organization) Organization
					.find("name = ?", organizationName).fetch().get(0);

			if (ideaDeveloper.canLeadOrganization(ideaDeveloper, organization)) {
				return "User is already an organization lead for this organization";
			} else {
				OrganizationLead organizationLead = null;
				if (OrganizationLead.count("ideaDeveloper=?", ideaDeveloper) == 0) {
					organizationLead = new OrganizationLead();
					organizationLead.ideaDeveloper = ideaDeveloper;
				} else {
					organizationLead = OrganizationLead.find("ideaDeveloper=?",
							ideaDeveloper).first();
				}

				organizationLead.ideaDeveloper = ideaDeveloper;
				organizationLead.manages.add(organization);
				organization.managers.add(organizationLead);
				organizationLead.save();
				organization.save();
				return "Organization lead assigned";
			}
		}

	}

	/**
	 * This method assigns an idea developer as an organizer to an entity
	 * 
	 * @author Maryam
	 * 
	 * @param ideaDeveloper
	 *            The idea developer that is going to be assigned
	 * @param entityName
	 *            The name of the entity that the idea developer will be
	 *            assigned to
	 * @return the string that would be viewed to the user according to whether
	 *         the idea developer is assigned or not and why
	 */

	public static String assignOrganizerToEntity(IdeaDeveloper ideaDeveloper,
			String entityName) {
		long countEntity = Entities.count("name = ?", entityName);
		if (countEntity == 0) {
			return "Entity not found";
		} else {
			Entities entity = (Entities) Entities.find("name = ?", entityName)
					.fetch().get(0);

			if (ideaDeveloper.canLeadEntity(ideaDeveloper, entity)) {
				return "User is already an organizer for this entity";
			} else {
				Organizer organizer = null;
				if (Organizer.count("ideaDeveloper=?", ideaDeveloper) == 0) {
					organizer = new Organizer();
					organizer.ideaDeveloper = ideaDeveloper;
				} else {
					organizer = Organizer
							.find("ideaDeveloper=?", ideaDeveloper).first();
				}

				organizer.manages.add(entity);
				entity.managers.add(organizer);
				organizer.save();
				entity.save();
				return "Organizer assigned";
			}

		}
	}

	/**
	 * This method assigns an idea developer as an organizer to a topic
	 * 
	 * @author Maryam
	 * 
	 * @param ideaDeveloper
	 *            The idea developer that is going to be assigned
	 * @param topicName
	 *            The name of the topic that the idea developer will be assigned
	 *            to
	 * @return the string that would be viewed to the user according to whether
	 *         the idea developer is assigned or not and why
	 */

	public static String assignOrganizerToTopic(IdeaDeveloper ideaDeveloper,
			String topicName) {
		long countTopic = Topic.count("title = ?", topicName);
		if (countTopic == 0) {
			return "Topic not found";
		} else {
			Topic topic = (Topic) Topic.find("title = ?", topicName).fetch()
					.get(0);

			if (ideaDeveloper.canLeadTopic(ideaDeveloper, topic)) {
				return "User is already an organizer for this entity";
			} else {
				Organizer organizer = null;
				if (Organizer.count("ideaDeveloper=?", ideaDeveloper) == 0) {
					organizer = new Organizer();
					organizer.ideaDeveloper = ideaDeveloper;
				} else {
					organizer = Organizer
							.find("ideaDeveloper=?", ideaDeveloper).first();
				}

				organizer.managedTopics.add(topic);
				topic.managers.add(organizer);
				organizer.save();
				topic.save();
				return "Organizer assigned";
			}

		}
	}

}